home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
TECHNICA
/
COMPUTER
/
H254.ZIP
/
IRITSM3S.ZIP
/
CAGD_LIB
/
CAGD_GEN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-26
|
21KB
|
612 lines
/******************************************************************************
* Cagd_gen.c - General routines used by all modules of CAGD_lib. *
*******************************************************************************
* Written by Gershon Elber, Mar. 90. *
******************************************************************************/
#ifdef __MSDOS__
#include <stdlib.h>
#include <alloc.h>
#endif /* __MSDOS__ */
#include <string.h>
#include "cagd_loc.h"
#ifdef __TURBOC__ /* Only for TC++ 1.0 and above. */
#define __DEBUG_MALLOC__
#endif /* __TURBOC__ */
#ifdef __DEBUG_FREE_BOGUS__ /* Detected freeing of bogus pointers. */
#define FREE_TABLE_SIZE 10000
static VoidPtr AllocPtrTable[FREE_TABLE_SIZE];
static int AllocNumPtrs = 0;
#endif /* __DEBUG_FREE_BOGUS__ */
/* Control of the linear order surface convertion to polygon: */
CagdLin2PolyType _CagdLin2Poly = CAGD_ONE_POLY_PER_COLIN;
static void CagdTransform(CagdRType **Points, int Len, int MaxCoord,
CagdBType IsNotRational, CagdRType Translate[3], CagdRType Scale);
static void CagdMatTransform(CagdRType **Points, int Len, int MaxCoord,
CagdBType IsNotRational, CagdMatStruct *Mat);
/******************************************************************************
* Allocate and reset all slots of a curve structure: *
******************************************************************************/
CagdCrvStruct *CagdCrvNew(CagdGeomType GType, CagdPointType PType, int Length)
{
int i, MaxAxis = CAGD_NUM_OF_PT_COORD(PType);
CagdCrvStruct *NewCrv = (CagdCrvStruct *) CagdMalloc(sizeof(CagdCrvStruct));
NewCrv -> GType = GType;
NewCrv -> PType = PType;
NewCrv -> Length = Length;
NewCrv -> Order = 0;
NewCrv -> KnotVector = NULL;
NewCrv -> Pnext = NULL;
NewCrv -> Points[0] = NULL; /* The rational element. */
for (i = !CAGD_IS_RATIONAL_PT(PType); i <= MaxAxis; i++)
NewCrv -> Points[i] = (CagdRType *) CagdMalloc(sizeof(CagdRType) *
Length);
for (i = MaxAxis + 1; i <= CAGD_MAX_PT_COORD; i++)
NewCrv -> Points[i] = NULL;
return NewCrv;
}
/******************************************************************************
* Allocate and reset all slots of a surface structure: *
******************************************************************************/
CagdSrfStruct *CagdSrfNew(CagdGeomType GType, CagdPointType PType, int ULength,
int VLength)
{
int i, MaxAxis = CAGD_NUM_OF_PT_COORD(PType);
CagdSrfStruct *NewSrf = (CagdSrfStruct *) CagdMalloc(sizeof(CagdSrfStruct));
NewSrf -> GType = GType;
NewSrf -> PType = PType;
NewSrf -> ULength = ULength;
NewSrf -> VLength = VLength;
NewSrf -> UOrder = 0;
NewSrf -> VOrder = 0;
NewSrf -> UKnotVector = NULL;
NewSrf -> VKnotVector = NULL;
NewSrf -> Pnext = NULL;
NewSrf -> Points[0] = NULL; /* The rational element. */
for (i = !CAGD_IS_RATIONAL_PT(PType); i <= MaxAxis; i++)
NewSrf -> Points[i] = (CagdRType *) CagdMalloc(sizeof(CagdRType) *
ULength * VLength);
for (i = MaxAxis + 1; i <= CAGD_MAX_PT_COORD; i++)
NewSrf -> Points[i] = NULL;
return NewSrf;
}
/******************************************************************************
* Allocate and reset all slots of a polygon structure: *
******************************************************************************/
CagdPolygonStruct *CagdPolygonNew(void)
{
CagdPolygonStruct *NewPoly = (CagdPolygonStruct *)
CagdMalloc(sizeof(CagdPolygonStruct));
NewPoly -> Pnext = NULL;
return NewPoly;
}
/******************************************************************************
* Allocate and reset all slots of a polyline structure: *
******************************************************************************/
CagdPolylineStruct *CagdPolylineNew(int Length)
{
CagdPolylineStruct *NewPoly = (CagdPolylineStruct *)
CagdMalloc(sizeof(CagdPolylineStruct));
NewPoly -> Pnext = NULL;
NewPoly -> Polyline = (CagdPtStruct *) CagdMalloc(sizeof(CagdPtStruct) *
Length);
NewPoly -> Length = Length;
return NewPoly;
}
/******************************************************************************
* Allocate and copy all slots of a curve structure: *
******************************************************************************/
CagdCrvStruct *CagdCrvCopy(CagdCrvStruct *Crv)
{
int i, MaxAxis = CAGD_NUM_OF_PT_COORD(Crv -> PType);
CagdCrvStruct *NewCrv = (CagdCrvStruct *) CagdMalloc(sizeof(CagdCrvStruct));
NewCrv -> GType = Crv -> GType;
NewCrv -> PType = Crv -> PType;
NewCrv -> Length = Crv -> Length;
NewCrv -> Order = Crv -> Order;
if (Crv -> KnotVector != NULL)
NewCrv -> KnotVector = BspKnotCopy(Crv -> KnotVector,
Crv -> Length + Crv -> Order);
else
NewCrv -> KnotVector = NULL;
NewCrv -> Pnext = NULL;
NewCrv -> Points[0] = NULL; /* The rational element. */
for (i = !CAGD_IS_RATIONAL_PT(Crv -> PType); i <= MaxAxis; i++) {
NewCrv -> Points[i] = (CagdRType *) CagdMalloc(sizeof(CagdRType) *
Crv -> Length);
GEN_COPY(NewCrv -> Points[i], Crv -> Points[i],
sizeof(CagdRType) * Crv -> Length);
}
for (i = MaxAxis + 1; i <= CAGD_MAX_PT_COORD; i++)
NewCrv -> Points[i] = NULL;
return NewCrv;
}
/******************************************************************************
* Allocate and copy all slots of a surface structure: *
******************************************************************************/
CagdSrfStruct *CagdSrfCopy(CagdSrfStruct *Srf)
{
int i, MaxAxis = CAGD_NUM_OF_PT_COORD(Srf -> PType);
CagdSrfStruct *NewSrf = (CagdSrfStruct *) CagdMalloc(sizeof(CagdSrfStruct));
NewSrf -> GType = Srf -> GType;
NewSrf -> PType = Srf -> PType;
NewSrf -> ULength = Srf -> ULength;
NewSrf -> VLength = Srf -> VLength;
NewSrf -> UOrder = Srf -> UOrder;
NewSrf -> VOrder = Srf -> VOrder;
if (Srf -> UKnotVector != NULL)
NewSrf -> UKnotVector = BspKnotCopy(Srf -> UKnotVector,
Srf -> ULength + Srf -> UOrder);
else
NewSrf -> UKnotVector = NULL;
if (Srf -> VKnotVector != NULL)
NewSrf -> VKnotVector = BspKnotCopy(Srf -> VKnotVector,
Srf -> VLength + Srf -> VOrder);
else
NewSrf -> VKnotVector = NULL;
NewSrf -> Pnext = NULL;
NewSrf -> Points[0] = NULL; /* The rational element. */
for (i = !CAGD_IS_RATIONAL_PT(Srf -> PType); i <= MaxAxis; i++) {
NewSrf -> Points[i] = (CagdRType *) CagdMalloc(sizeof(CagdRType) *
Srf -> ULength * Srf -> VLength);
GEN_COPY(NewSrf -> Points[i], Srf -> Points[i],
sizeof(CagdRType) * Srf -> ULength * Srf -> VLength);
}
for (i = MaxAxis + 1; i <= CAGD_MAX_PT_COORD; i++)
NewSrf -> Points[i] = NULL;
return NewSrf;
}
/******************************************************************************
* Allocate and copy all slots of a polygon structure: *
******************************************************************************/
CagdPolygonStruct *CagdPolygonCopy(CagdPolygonStruct *Poly)
{
CagdPolygonStruct *NewPoly = (CagdPolygonStruct *)
CagdMalloc(sizeof(CagdPolygonStruct));
GEN_COPY(NewPoly, Poly, sizeof(CagdPolygonStruct));
NewPoly -> Pnext = NULL;
return NewPoly;
}
/******************************************************************************
* Allocate and copy all slots of a polyline structure: *
******************************************************************************/
CagdPolylineStruct *CagdPolylineCopy(CagdPolylineStruct *Poly)
{
CagdPolylineStruct *NewPoly = (CagdPolylineStruct *)
CagdMalloc(sizeof(CagdPolylineStruct));
NewPoly -> Polyline = (CagdPtStruct *) CagdMalloc(sizeof(CagdPtStruct) *
Poly -> Length);
GEN_COPY(NewPoly -> Polyline, Poly -> Polyline,
sizeof(CagdPtStruct) * Poly -> Length);
NewPoly -> Pnext = NULL;
NewPoly -> Length = Poly -> Length;
return NewPoly;
}
/******************************************************************************
* Deallocate and free all slots of a curve structure: *
******************************************************************************/
void CagdCrvFree(CagdCrvStruct *Crv)
{
int i, MaxAxis = CAGD_NUM_OF_PT_COORD(Crv -> PType);
for (i = !CAGD_IS_RATIONAL_SRF(Crv); i <= MaxAxis; i++)
CagdFree((VoidPtr) Crv -> Points[i]);
if (Crv -> KnotVector != NULL)
CagdFree((VoidPtr) Crv -> KnotVector);
CagdFree((VoidPtr) Crv);
}
/******************************************************************************
* Deallocate and free a curve structure list: *
******************************************************************************/
void CagdCrvFreeList(CagdCrvStruct *CrvList)
{
CagdCrvStruct *CrvTemp;
while (CrvList) {
CrvTemp = CrvList -> Pnext;
CagdCrvFree(CrvList);
CrvList = CrvTemp;
}
}
/******************************************************************************
* Deallocate and free all slots of a surface structure: *
******************************************************************************/
void CagdSrfFree(CagdSrfStruct *Srf)
{
int i, MaxAxis = CAGD_NUM_OF_PT_COORD(Srf -> PType);
for (i = !CAGD_IS_RATIONAL_SRF(Srf); i <= MaxAxis; i++)
CagdFree((VoidPtr) Srf -> Points[i]);
if (Srf -> UKnotVector != NULL)
CagdFree((VoidPtr) Srf -> UKnotVector);
if (Srf -> VKnotVector != NULL)
CagdFree((VoidPtr) Srf -> VKnotVector);
CagdFree((VoidPtr) Srf);
}
/******************************************************************************
* Deallocate and free a curve structure list: *
******************************************************************************/
void CagdSrfFreeList(CagdSrfStruct *SrfList)
{
CagdSrfStruct *SrfTemp;
while (SrfList) {
SrfTemp = SrfList -> Pnext;
CagdSrfFree(SrfList);
SrfList = SrfTemp;
}
}
/******************************************************************************
* Deallocate and free a curve structure list: *
******************************************************************************/
void CagdPolylineFree(CagdPolylineStruct *Poly)
{
CagdFree((VoidPtr) Poly -> Polyline);
CagdFree((VoidPtr) Poly);
}
/******************************************************************************
* Deallocate and free a curve structure list: *
******************************************************************************/
void CagdPolylineFreeList(CagdPolylineStruct *PolyList)
{
CagdPolylineStruct *PolyTemp;
while (PolyList) {
PolyTemp = PolyList -> Pnext;
CagdPolylineFree(PolyList);
PolyList = PolyTemp;
}
}
/******************************************************************************
* Deallocate and free a curve structure list: *
******************************************************************************/
void CagdPolygonFree(CagdPolygonStruct *Poly)
{
CagdFree((VoidPtr) Poly);
}
/******************************************************************************
* Deallocate and free a curve structure list: *
******************************************************************************/
void CagdPolygonFreeList(CagdPolygonStruct *PolyList)
{
CagdPolygonStruct *PolyTemp;
while (PolyList) {
PolyTemp = PolyList -> Pnext;
CagdPolygonFree(PolyList);
PolyList = PolyTemp;
}
}
#if defined(__DEBUG_MALLOC__) || defined(__DEBUG_FREE_BOGUS__)
/*****************************************************************************
* My Routine to allocate dynamic memory. All program requests must call this *
* routine (no direct call to malloc). Dies if no memory. *
*****************************************************************************/
static void AllocError(const char *Msg, VoidPtr *p)
{
char s[128];
/* Note s is practically ignored, but you may want to print it. */
#ifdef __MSDOS__
sprintf(s, "%s, Ptr = %p\n", Msg, p);
#else
sprintf(s, "%s, Ptr = %lx\n", Msg, p);
#endif /* __MSDOS__ */
FATAL_ERROR(CAGD_ERR_ALLOC_ERR);
}
#endif /* __DEBUG_MALLOC__ || __DEBUG_FREE_BOGUS__ */
/*****************************************************************************
* My Routine to allocate dynamic memory. All program requests must call this *
* routine (no direct call to malloc). Dies if no memory. *
*****************************************************************************/
VoidPtr CagdMalloc(unsigned size)
{
VoidPtr p;
if ((p = malloc(size)) != NULL) {
# ifdef __DEBUG_FREE_BOGUS__
int i;
/* Save the allocated pointer so we can search for it when freed. */
for (i = 0; i < AllocNumPtrs; i++)
if (AllocPtrTable[i] == NULL) {
AllocPtrTable[i] = p;
break;
}
if (i >= AllocNumPtrs) AllocPtrTable[AllocNumPtrs++] = p;
# endif /* __DEBUG_FREE_BOGUS__ */
return p;
}
CagdFatalError(CAGD_ERR_NOT_ENOUGH_MEM);
return NULL; /* Make warnings silent. */
}
/*****************************************************************************
* My Routine to free dynamic memory. All program requests must call this *
* routine (no direct call to free). *
*****************************************************************************/
void CagdFree(VoidPtr p)
{
#ifdef __DEBUG_FREE_BOGUS__
int i;
/* Compare the freed pointer with the list of allocated ones. */
for (i = 0; i < AllocNumPtrs; i++) if (AllocPtrTable[i] == p) break;
if (i >= AllocNumPtrs) AllocError("Free unallocated pointer", p);
#endif /* __DEBUG_FREE_BOGUS__ */
#ifdef __DEBUG_MALLOC__
switch (heapcheck()) {
case _HEAPCORRUPT:
AllocError("Heap is corrupted", p);
break;
case _BADNODE:
AllocError("Attempt to free a bogus pointer", p);
break;
case _FREEENTRY:
AllocError("Attempt to free an already freed pointer", p);
break;
case _HEAPOK:
case _HEAPEMPTY:
case _USEDENTRY:
break;
default:
AllocError("Allocation error", p);
break;
}
#endif /* __DEBUG_MALLOC__ */
free(p);
}
/******************************************************************************
* Linear transform in place given Crv as specified by Translate and Scale. *
******************************************************************************/
void CagdCrvTransform(CagdCrvStruct *Crv, CagdRType Translate[3],
CagdRType Scale)
{
switch (Crv -> GType) {
case CAGD_CBEZIER_TYPE:
case CAGD_CBSPLINE_TYPE:
CagdTransform(Crv -> Points,
Crv -> Length,
CAGD_NUM_OF_PT_COORD(Crv -> PType),
!CAGD_IS_RATIONAL_CRV(Crv),
Translate,
Scale);
break;
case CAGD_CPOWER_TYPE:
FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
break;
default:
FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
break;
}
}
/******************************************************************************
* Linear transform in place given Srf as specified by Translate and Scale. *
******************************************************************************/
void CagdSrfTransform(CagdSrfStruct *Srf, CagdRType Translate[3],
CagdRType Scale)
{
switch (Srf -> GType) {
case CAGD_SBEZIER_TYPE:
case CAGD_SBSPLINE_TYPE:
CagdTransform(Srf -> Points,
Srf -> ULength * Srf -> VLength,
CAGD_NUM_OF_PT_COORD(Srf -> PType),
!CAGD_IS_RATIONAL_SRF(Srf),
Translate,
Scale);
break;
case CAGD_SPOWER_TYPE:
FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
break;
default:
FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
break;
}
}
/******************************************************************************
* Linear transform in place given Data as specified by Translate and Scale. *
******************************************************************************/
static void CagdTransform(CagdRType **Points, int Len, int MaxCoord,
CagdBType IsNotRational, CagdRType Translate[3], CagdRType Scale)
{
int i, j;
if (IsNotRational)
for (i = 1; i <= MaxCoord; i++)
for (j = 0; j < Len; j++)
Points[i][j] = (Points[i][j] + Translate[i - 1]) * Scale;
else
for (i = 1; i <= MaxCoord; i++)
for (j = 0; j < Len; j++)
Points[i][j] = (Points[i][j] +
Translate[i - 1] * Points[W][j]) * Scale;
}
/******************************************************************************
* Linear transform in place the given Crv as specified by Mat. *
******************************************************************************/
void CagdCrvMatTransform(CagdCrvStruct *Crv, CagdMatStruct *Mat)
{
switch (Crv -> GType) {
case CAGD_CBEZIER_TYPE:
case CAGD_CBSPLINE_TYPE:
CagdMatTransform(Crv -> Points,
Crv -> Length,
CAGD_NUM_OF_PT_COORD(Crv -> PType),
!CAGD_IS_RATIONAL_CRV(Crv),
Mat);
break;
case CAGD_CPOWER_TYPE:
FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
break;
default:
FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
break;
}
}
/******************************************************************************
* Linear transform in place the given Srf as specified by Mat. *
******************************************************************************/
void CagdSrfMatTransform(CagdSrfStruct *Srf, CagdMatStruct *Mat)
{
switch (Srf -> GType) {
case CAGD_SBEZIER_TYPE:
case CAGD_SBSPLINE_TYPE:
CagdMatTransform(Srf -> Points,
Srf -> ULength * Srf -> VLength,
CAGD_NUM_OF_PT_COORD(Srf -> PType),
!CAGD_IS_RATIONAL_SRF(Srf),
Mat);
break;
case CAGD_SPOWER_TYPE:
FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
break;
default:
FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
break;
}
}
/******************************************************************************
* Linear transform in place the given Data as specified by Mat. *
******************************************************************************/
static void CagdMatTransform(CagdRType **Points, int Len, int MaxCoord,
CagdBType IsNotRational, CagdMatStruct *Mat)
{
int i, j;
CagdRType P[4], Q[4];
if (IsNotRational)
for (i = 0; i < Len; i++) {
for (j = 1; j <= MaxCoord; j++) P[j - 1] = Points[j][i];
P[3] = 1.0;
/* Zero unused coords. */
for (j = MaxCoord + 1; j < 3; i++) P[j - 1] = 0.0;
CagdMultMatVec(Mat, P, Q);
for (j = 1; j <= MaxCoord; j++) Points[j][i] = Q[j - 1];
}
else
for (i = 0; i < Len; i++) {
for (j = 1; j <= MaxCoord; j++) P[j - 1] = Points[j][i];
P[3] = Points[W][i];
/* Zero unused coords. */
for (j = MaxCoord + 1; j < 3; i++) P[j - 1] = 0.0;
CagdMultMatVec(Mat, P, Q);
for (j = 1; j <= MaxCoord; j++) Points[j][i] = Q[j - 1];
Points[W][i] = Q[3];
}
}
/*****************************************************************************
* Routine to create one polygon given its vertices. *
*****************************************************************************/
CagdPolygonStruct *_CagdMakePolygon(CagdBType ComputeNormals,
CagdPtStruct *Pt1,
CagdPtStruct *Pt2,
CagdPtStruct *Pt3,
CagdVecStruct *Nl1,
CagdVecStruct *Nl2,
CagdVecStruct *Nl3)
{
CagdPolygonStruct *Poly = CagdPolygonNew();
CAGD_COPY_POINT(Poly -> Polygon[0], *Pt1);
CAGD_COPY_POINT(Poly -> Polygon[1], *Pt2);
CAGD_COPY_POINT(Poly -> Polygon[2], *Pt3);
if (ComputeNormals) {
CAGD_COPY_VECTOR(Poly -> Normal[0], *Nl1);
CAGD_COPY_VECTOR(Poly -> Normal[1], *Nl2);
CAGD_COPY_VECTOR(Poly -> Normal[2], *Nl3);
}
else {
CAGD_RESET_VECTOR(Poly -> Normal[0]);
CAGD_RESET_VECTOR(Poly -> Normal[1]);
CAGD_RESET_VECTOR(Poly -> Normal[2]);
}
return Poly;
}
/*****************************************************************************
* Set the way (co)linear surfaces are converted into polygons. *
*****************************************************************************/
void CagdSetLinear2Poly(CagdLin2PolyType Lin2Poly)
{
_CagdLin2Poly = Lin2Poly;
}